﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.InteropServices;
using Raven.Abstractions.Extensions;
using Raven.Client.Document;
using Raven.Client.Embedded;
using Raven.Client.Linq;

namespace HotCopperUserScanService
{
    public class PostsDatabase
    {
        private static DocumentStore _documentStore;
        public static bool InMemory { get; set; }

        public static void Insert(IEnumerable<Post> posts)
        {
            InitializeDocumentStore();
            using (var session = _documentStore.OpenSession())
            {
                posts.ForEach(p => session.Store(p));
                session.SaveChanges();
            }
        
        }

        public static void Update(IEnumerable<Post> posts)
        {
            InitializeDocumentStore();
            using (var session = _documentStore.OpenSession())
            {
                session.Advanced.MaxNumberOfRequestsPerSession = 200;
                posts.ForEach(p =>
                {
                    var toUpdate = session.Load<Post>(p.Id);
                    //only uodate the editable field
                    toUpdate.Code = p.Code;
                    toUpdate.FirstPrice = p.FirstPrice;
                    toUpdate.Target = p.Target;
                });
                session.SaveChanges();
            }

        }

        private static void InitializeDocumentStore()
        {
            if (_documentStore != null) return;

            _documentStore = new EmbeddableDocumentStore()
            {
                RunInMemory = InMemory,
                DataDirectory = Path.Combine(Environment.CurrentDirectory, "Data")
            };
            _documentStore.Initialize();
         
        }

        public static ICollection<Post> Retrieve(string id)
        {
            InitializeDocumentStore();
            using (var session = _documentStore.OpenSession())
            {
                var results = session.Query<Post>().Where(p => p.Username == id).OrderByDescending(p => p.DateTime).ToList();
                return results;
            }
        }

        public static ICollection<Post> Retrieve(string id, int maxToReturn)
        {
            InitializeDocumentStore();
            using (var session = _documentStore.OpenSession())
            {
                var results = session.Query<Post>().Where(p => p.Username == id).OrderByDescending(p => p.DateTime).Take(maxToReturn).ToList();
                return results;
            }
        }

        public static ICollection<Post> Retrieve(int maxToReturn)
        {
            InitializeDocumentStore();
            using (var session = _documentStore.OpenSession())
            {
                var results = session.Query<Post>().OrderByDescending(p => p.DateTime).Take(maxToReturn).ToList();
                return results;
            }
        }

        public static void Delete(ICollection<Post> posts)
        {
            InitializeDocumentStore();
            using (var session = _documentStore.OpenSession())
            {
                foreach (var post in posts)
                {
                    Post post1 = post;
                    var foundPost = session.Query<Post>().Single(p => p.DateTime == post1.DateTime && p.Username == post1.Username);
                    session.Delete(foundPost);
                }
                session.SaveChanges();
            }
        }

        public static void CloseDown()
        {
            _documentStore.Dispose();
            _documentStore = null;
        }

        public static void DeleteAll()
        {
            InitializeDocumentStore();
            using (var session = _documentStore.OpenSession())
            {
                var posts = session.Query<Post>().Where(p => p.DateTime > new DateTime()).ToList();
                foreach (var post in posts)
                {
                    session.Delete(post);
                }
                session.SaveChanges();
            }
        }

    }
}